﻿using LS.Infrastructure.ExceptionExtension;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using NLog;
using QInfrastructure.Interfaces;
using QInfrastructure.Utils;
using QInfrastructure.WebCore.Filters;
using QInfrastructure.WebCore.Models;
using System.Reflection;
using System.Text.Json;
using QInfrastructure.Services;
using QInfrastructure.Models;
using QInfrastructure.Models.SystemManager;
using QInfrastructure.Interfaces.SystemManager;
using QInfrastructure.Services.QDbContext;

namespace QInfrastructure.WebCore;
#nullable disable

public class InitAppSetting
{


   
    private static Lazy<Logger> logger = new Lazy<Logger>(() => LogManager.GetCurrentClassLogger(), true);


    public static void InitConfiguration(WebApplicationBuilder builder)
    {
		var dbconnectionStr = builder.Configuration.GetConnectionString("MySQLServerConnection");
		MySqlDbContext.SetDbConfiguration(dbconnectionStr, LS.Infrastructure.DbAccess.LSDbType.MySql, "5.7.37");
		MySqlDbContext.QueryFilterTenantId = false;

        var appName = builder.Configuration.GetValue<string>("AppName")??"XXXX系统";
        AppRuntimes.Instance.AppName = appName;
       

	}


    public static void InitExceptionHandler(WebApplication app)
    {
        app.UseExceptionHandler(builder =>
        {
            builder.Run(async context =>
            {
                var ex = context.Features.Get<IExceptionHandlerFeature>();

                var result = new ResponseData<string>();
                result.Code = context.Response.StatusCode;
                result.Message = ex.Error.Message;
                var errorpath = context.Request.Path;
                var errmsg = ex.Error.Message;
                var errtractmsg = ex.Error.StackTrace;
                var datestr = DateTime.Now.ToDateTimeStr();
                datestr = "----------------------------------------------" + datestr + "-----------------------------------------------------";
                logger.Value.Error(datestr);
                logger.Value.Error(errorpath);
                logger.Value.Error(errmsg);
                logger.Value.Error(errtractmsg);


                context.Response.StatusCode = 500;
                context.Response.ContentType = "application/json";
                await context.Response.WriteAsync(JsonSerializer.Serialize(result));

            });
        });
    }


    public static void InitPermission(WebApplicationBuilder builder)
    {
        builder.Services.AddScoped<PermissionFilter>();
        var assemblyName = "QInfrastructure.WebCore";
        var assemblys = AppDomain.CurrentDomain.GetAssemblies().Where(x => !string.IsNullOrWhiteSpace(x.GetName().Name) && x.GetName().Name.Contains(assemblyName)).ToList();
        for (int i = 0; i < assemblys.Count; i++)
        {
            var assembly = assemblys[i];
            var alltypes = assembly.GetTypes();
            foreach (var type in alltypes)
            {
                var methods = type.GetMethods().Where(x => x.CustomAttributes.Any(m => m.AttributeType.Name.Contains("QPermission"))).ToList();
                if (methods.Count > 0)
                {
                    var areaAttribute = type.GetCustomAttribute<AreaAttribute>();
                    var areaName = areaAttribute?.RouteValue;
                    for (int j = 0; j < methods.Count; j++)
                    {

                        var method = methods[j];
                        var qpermission = method.GetCustomAttribute<QPermissionAttribute>();
                        var permissionKey = qpermission.PermissionKey;
                        var controller = type.Name;
                        var methodName = method.Name;
                        var key = $"{areaName}_{controller}_{methodName}";
                        AppRuntimes.Instance.PermissionDictionary.TryAdd(key, permissionKey);
                    }
                }
            }
        }

    }



    public static void InitService(WebApplicationBuilder builder)
    {
        QInitService.Init();
        var assemblys = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(t => t.GetName().Name.Contains("QInfrastructure.Services"));
        if (assemblys == null) throw new BusinessException("注入服务失败");
        var serviceTypes = assemblys.GetExportedTypes().Where(t => t.GetInterfaces().Length > 0).ToList();
        if (serviceTypes.Count <= 0) return;
        List<Type> interfaceTypes=new List<Type> { typeof(TService) };
        for (int i = 0; i < serviceTypes.Count; i++)
        {
            for (int j = 0; j < interfaceTypes.Count; j++)
            {
                if (serviceTypes[i].GetInterfaces().Any(t => t.Name == interfaceTypes[j].Name))
                {
                    var impInterface = serviceTypes[i].GetInterfaces().FirstOrDefault(x => x.GetInterfaces().Any(m => m.Name == interfaceTypes[j].Name));
                    if (impInterface != null)
                    {
                        builder.Services.AddSingleton(impInterface, serviceTypes[i]);
                    }
                }
            }
        }
    }




    //注册缓存信息

    public static void InitQCacheService(WebApplication app)
    {
        QInfrastructureCache.CacheActions.Add(typeof(SystemUser).FullName, () =>
        {
            var users = app.Services.GetService<TSysQCache>().GetEntityFromDb<SystemUser>();
            QInfrastructureCache.AddOrUpdateQCache(typeof(SystemUser).FullName, users);
        });

        QInfrastructureCache.CacheActions.Add(typeof(SystemUserTheme).FullName, () =>
        {
			var themes = app.Services.GetService<TSysQCache>().GetEntityFromDb<SystemUserTheme>();
			QInfrastructureCache.AddOrUpdateQCache(typeof(SystemUserTheme).FullName, themes);
		});


    }




}
